package com.xinhe.web.service;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.xinhe.web.common.BusinessException;
import com.xinhe.web.common.Result;
import com.xinhe.web.entity.*;
import com.xinhe.web.reposity.AssetCountRepository;
import com.xinhe.web.reposity.AssetDetailRepository;
import com.xinhe.web.reposity.MemberRepository;
import com.xinhe.web.reposity.TeaOilCardRecordRepository;
import com.xinhe.web.response.TeaOilCardRecordView;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.inject.Provider;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
public class TeaOilCardRecordService {
    //查询工厂
    private JPAQueryFactory queryFactory;
    @Autowired
    private Provider<EntityManager> entityManager;
    @PostConstruct
    public void init() {
        queryFactory = new JPAQueryFactory(entityManager);
    }
    @Autowired
    MemberRepository memberRepository;
    @Autowired
    TeaOilCardRecordRepository teaOilCardRecordRepository;
    @Autowired
    AssetDetailRepository assetDetailRepository;
    AssetCountRepository assetCountRepository;
    public QueryResults<TeaOilCardRecordView> pageTeaOilCardRecord(String queryWord, String status,
                                                                   int pageNum, int pageSize) {
        QTeaOilCardRecord qTeaOilCardRecord = QTeaOilCardRecord.teaOilCardRecord;
        QMember qMember = QMember.member; ;
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(qMember.removed.eq(0));
        if (StringUtils.isNotEmpty(queryWord)) {
            builder.and(qMember.name.contains(queryWord).or(qMember.mobile.contains(queryWord)));
        }
        if (!Objects.isNull(status)) {
            builder.and(qTeaOilCardRecord.status.contains(status));
        }
        return queryFactory.select(
                Projections.bean(
                        TeaOilCardRecordView.class,
                        qTeaOilCardRecord.id,
                        qTeaOilCardRecord.fUserId,
                        qTeaOilCardRecord.number,
                        qTeaOilCardRecord.id,
                        qTeaOilCardRecord.status,
                        qTeaOilCardRecord.type,
                        qMember.name,
                        qMember.mobile
                )
        ).from(qTeaOilCardRecord)
                .leftJoin(qMember).on(qMember.fUserId.eq(qTeaOilCardRecord.fUserId).and(qMember.removed.eq(0)))
                .where(builder).offset(pageNum * pageSize).limit(pageSize).fetchResults();
    }
    @Transactional
    public Result saveCheck(List<Long> ids,String result,String remark) {
        List<TeaOilCardRecord> teaOilCardRecords = teaOilCardRecordRepository.findByIdIn(ids);
        if (CollectionUtils.isNotEmpty(teaOilCardRecords)) {
            for (TeaOilCardRecord wr : teaOilCardRecords) {
                if ("APPLY" == wr.getStatus()) {
                    if ("FAILURE".equals(result)) {
                        //1、保存资产流水。资产类型是茶油卡。交易类型是兑换茶油卡拒绝。兑换数量
                        //2、更新资产统计表AssetCount里面的剩余茶油卡数量remainder
                        saveRemainderAsset(wr.getfUserId(),"TEA_OIL_CARD","USER_EXCHANGE_REJECT",
                                new BigDecimal(wr.getNumber().intValue()),wr.getId());
                        wr.setStatus("REJECT");
                        //wr.setRemark(remark);
                        teaOilCardRecordRepository.saveAndFlush(wr);
                        continue;
                    }if ("SUCCESS".equals(result)) {
                        wr.setStatus("SUCCESS");
                        teaOilCardRecordRepository.saveAndFlush(wr);
                        //1、保存资产流水。资产类型是茶油。交易类型是兑换茶油卡已领取成功。兑换数量
                        //2、更新资产统计表AssetCount里面的剩余茶油卡数量remainder
                        saveRemainderAsset(wr.getfUserId(),"TEA_OIL","ADOPTED_OIL_CARD_EXCHANGE_TEA_OIL",
                                new BigDecimal(wr.getNumber().intValue()),wr.getId());
                    }
                }
            }
        } else {
            throw new BusinessException(1001,"未选择数据");
        }
        return Result.ok();
    }
    @Transactional
    public Result saveTeaOilCardRecord(Integer number,Integer type,Long userId) {
        Member member = memberRepository.findByUserId(userId);
        if ("FREEZE".equals(member.getMemberStatus())) {
            return Result.failed(10004,"账号已被冻结!");
        }
        AssetCount assetCount = assetCountRepository.findByTypeAndUserId("TEA_OIL_CARD",userId);
        if (Objects.isNull(assetCount)) {
            throw new BusinessException(10005,"资产里无茶油卡记录");
        }
        if (assetCount.getRemainder().compareTo(new BigDecimal(number.intValue())) < 0) {
            throw new BusinessException(10006,"兑换数量超出已有数量");
        }
        //保存茶油卡兑换记录
        TeaOilCardRecord teaOilCardRecord = new TeaOilCardRecord();
        teaOilCardRecord.setStatus("APPLY");
        teaOilCardRecord.setType(type);
        teaOilCardRecord.setfUserId(userId);
        teaOilCardRecord.setNumber(number);
        teaOilCardRecordRepository.save(teaOilCardRecord);
        //1、保存资产流水。资产类型是茶油卡。交易类型是兑换茶油。交易金额记作：负兑换数量
        //2、更新资产统计表AssetCount里面的剩余茶油卡数量remainder
        saveRemainderAsset(teaOilCardRecord.getfUserId(),"TEA_OIL_CARD","ADOPTED_OIL_CARD_EXCHANGE_TEA_OIL",
                (new BigDecimal(number.intValue())).negate(),teaOilCardRecord.getId());
        return Result.ok();
    }
    public void saveRemainderAsset(Long userId,String assetType,String tradeType,
                                     BigDecimal tradeAmount,Long fBusinessId) {
        //兑换茶油
        if ("TEA_OIL_CARD".equals(assetType) && "ADOPTED_OIL_CARD_EXCHANGE_TEA_OIL".equals(tradeType)){
            //更新剩余茶油卡数量。但是要注意还没审核，可能审核那里给拒绝兑换了，这样你就得把这个剩余数量更新回来
            AssetCount assetCount = assetCountRepository.findByTypeAndUserId(assetType, userId);
            BigDecimal remainder= assetCount.getRemainder().add(tradeAmount);//因为tradeAmount传过来的是负数
            assetCount.setRemainder(remainder);
            assetCountRepository.saveAndFlush(assetCount);
            //新增资产流水
            AssetDetail assetDetail = new AssetDetail();
            assetDetail.setfUserId(userId);
            assetDetail.setfBusinessId(fBusinessId);
            assetDetail.setDtype("AssetDetail");
            assetDetail.setAssetType(assetType);
            assetDetail.setTradeType(tradeType);
            //交易数量。如果是兑换类的记作负数
            assetDetail.setTradeAmount(tradeAmount);
            //剩余数量
            assetDetail.setRemainder(assetCount.getRemainder());
            assetDetail.setCreateTime(new Date());
            assetDetail.setfCreateUserId(userId);
            assetDetailRepository.save(assetDetail);
        }
        //兑换茶油卡审核拒绝。需要将数量加回去，因为人家申请的时候就预扣了，你拒绝了，那就得给人家加回去
        if ("TEA_OIL_CARD".equals(assetType) && "USER_EXCHANGE_REJECT".equals(tradeType)){
            //更新剩余茶油卡数量。由于拒绝了，数量要加回去
            AssetCount assetCount = assetCountRepository.findByTypeAndUserId(assetType, userId);
            assetCount.setRemainder(assetCount.getRemainder().add(tradeAmount));
            assetCountRepository.saveAndFlush(assetCount);
            //新增资产流水
            AssetDetail assetDetail = new AssetDetail();
            assetDetail.setfUserId(userId);
            assetDetail.setfBusinessId(fBusinessId);
            assetDetail.setDtype("AssetDetail");
            assetDetail.setAssetType(assetType);
            assetDetail.setTradeType(tradeType);
            //交易数量。
            assetDetail.setTradeAmount(tradeAmount);
            //剩余数量
            assetDetail.setRemainder(assetCount.getRemainder());
            assetDetail.setCreateTime(new Date());
            assetDetail.setfCreateUserId(userId);
            assetDetailRepository.save(assetDetail);
        }
        //兑换茶油审核已领取成功。资产表剩余量不用修改了，因为申请的时候已经扣除了
        if ("TEA_OIL".equals(assetType) && "ADOPTED_OIL_CARD_EXCHANGE_TEA_OIL".equals(tradeType)){
            //更新剩余茶油卡数量。
            AssetCount assetCount = assetCountRepository.findByTypeAndUserId(assetType, userId);
            assetCount.setRemainder(assetCount.getRemainder().add(tradeAmount));
            assetCountRepository.saveAndFlush(assetCount);
            //新增资产流水（茶油领取）
            AssetDetail assetDetail = new AssetDetail();
            assetDetail.setfUserId(userId);
            assetDetail.setfBusinessId(fBusinessId);
            assetDetail.setDtype("AssetDetail");
            assetDetail.setAssetType(assetType);
            assetDetail.setTradeType(tradeType);
            //交易数量。
            assetDetail.setTradeAmount(tradeAmount);
            //剩余数量.注意当资产类型是茶油时，这个是指你领取多少茶油剩余就写多少，可以理解成给你多少瓶茶油了
            assetDetail.setRemainder(tradeAmount);
            assetDetail.setCreateTime(new Date());
            assetDetail.setfCreateUserId(userId);
            assetDetailRepository.save(assetDetail);
        }
        //赠送云茶籽。
        if ("YUN_CHA_SEED".equals(assetType) && "ADDITIONAL_GIFT_YUN_CHA_SEED".equals(tradeType)){
            //更新剩余云茶籽数量。
            AssetCount assetCount = assetCountRepository.findByTypeAndUserId(assetType, userId);
            assetCount.setRemainder(assetCount.getRemainder().add(tradeAmount));
            assetCountRepository.saveAndFlush(assetCount);
            //新增资产流水（茶油领取）
            AssetDetail assetDetail = new AssetDetail();
            assetDetail.setfUserId(userId);
            assetDetail.setfBusinessId(fBusinessId);
            assetDetail.setDtype("AssetDetail");
            assetDetail.setAssetType(assetType);
            assetDetail.setTradeType(tradeType);
            //交易数量。
            assetDetail.setTradeAmount(tradeAmount);
            //剩余数量.注意当资产类型是茶油时，这个是指你领取多少茶油剩余就写多少，可以理解成给你多少瓶茶油了
            assetDetail.setRemainder(tradeAmount);
            assetDetail.setCreateTime(new Date());
            assetDetail.setfCreateUserId(userId);
            assetDetailRepository.save(assetDetail);
        }
    }

    public Result delete(Long teaOilCardRecordId) {
        return Result.ok();
    }

    public Result findById(Long teaOilCardRecordId) {
        return Result.ok();
    }

}
